/* $Id:job.cc $ */
/*
   Copyright (C) 2007 by Jurjen Stellingwerff <jurjen@stwerff.xs4all.nl>
   Part of the Moros Project http://moros.sourceforge.net/

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 3.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.

   See the COPYING file for more details.
*/

#define DEBUG_ROUTINE "job"

#include <sstream>
#include <fstream>
#include "../general/util.h"
#include "../general/log.h"
#include "../general/channel.h"
#include "job.h"
#include "item.h"
#include "../general/general.h"

job::job() {
    name="";
    description="";
    special=map<string,class material>();
    status=0;
}

// Field : name

const string job::getName() const { return name; }
void job::setName(const string v) { name=v; }

// Field : description

const string job::getDescription() const { return description; }
void job::setDescription(const string v) { description=v; }

// Field : special

class material& job::getSpecial(const string v) { return special[v]; }
list<class material>& job::listSpecial() {
    static list<class material> res;
    res.clear();
    loopMap(special,v,class material) {
        res.push_back(*v);
    }
    res.sort();
    return res;
}
void job::setSpecial(class material &v) {
    special[v.getItem().getName()]=v;
}
void job::delSpecial(const string v) { special.erase(v); }
const bool job::isSpecial(const string v) const { return special.count(v)>0; }

// Field : status

const int job::getStatus() const { return status; }
void job::setStatus(const int v) { status=v; }

void job::save(class channel &ch) {
    ch.write("job", "");
    ch.write("n", getName());
    ch.write("d", getDescription());
    loopJobSpecial(this, s_special) {
        s_special->save(ch);
    }
    ch.write("st", getStatus());
}

void job::load(class channel &ch) {
    if (ch.key=="n" || ch.key=="name") { setName(ch.value); ch.next(); }
    if (ch.key=="d" || ch.key=="description") { setDescription(ch.value); ch.next(); }
    while (ch.key=="material" || ch.key=="special") {
        ch.next();
        class material rec;
        rec.load(ch);
        setSpecial(rec);
    }
    if (ch.key=="st" || ch.key=="status") { setStatus(atoi(ch.value.c_str())); ch.next(); }
}

void job::xml(ofstream &f, int l, int r) {
    f << ncpy(l, "  ") << "<job name=\"" << xml_encode(getName()) <<
    "\" description=\"" << xml_encode(getDescription()) <<
    "\" status=\"" << getStatus() <<
    "\">" << endl;
    if (r==0) {
        loopJobSpecial(this, s_special) {
            s_special->xml(f,l+1);
        }
    }
    f << ncpy(l, "  ") << "</job>" << endl;
}

// Repository

jobRepository job_repo;

class job& jobRepository::getJob(const string v) { return jobs[v]; }
void jobRepository::setJob(class job& v) {
    if (v.getName()=="") throw unnamed();
    jobs[v.getName()]=v;
}
map<string,class job>& jobRepository::listJob() { return jobs; }
void jobRepository::delJob(const string v) { jobs.erase(v); }
const bool jobRepository::isJob(const string v) const { return jobs.count(v)>0; }
void jobRepository::save(class channel &ch) {
    loopJobs(rec) {
        rec->save(ch);
    }
}

bool jobRepository::load(class channel &ch) {
    if (ch.key=="job") {
        ch.next();
        class job rec;
        rec.load(ch);
        setJob(rec);
        return true;
    }
    return false;
}
